﻿using System;
using System.ComponentModel;
using System.IO;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace AT.IBMS.Framework.Controls
{

    public partial class AspNetPager
    {

        #region Private fields

        private enum NavigationButton : byte
        {
            First,
            Prev,
            Next,
            Last
        }

        //private string cssClassName;
        private string inputPageIndex;
        private string currentUrl;
        private string queryString;
        private AspNetPager cloneFrom;
        private static readonly object EventPageChanging = new object();
        private static readonly object EventPageChanged = new object();
        //bool pageChangeEventHandled = false; 
        //AspNetPager Version number, does not use reflection for perfomance reason
        //const string VersionNumber = "7.3.2";

        #endregion


        #region Navigation Buttons

        /// <summary>
        /// 获取或设置一个值，该值批示当鼠标指针悬停在导航按钮上时是否显示工具提示。
        /// </summary>
        /// <value>
        /// boolean值，默认值为false，即不显示工具提示。
        /// </value>
        [Browsable(true), ANPCategory("cat_Navigation"), DefaultValue(false), ANPDescription("desc_ShowNavigationToolTip"), Themeable(true)]
        public bool ShowNavigationToolTip
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ShowNavigationToolTip;
                object obj = ViewState["ShowNvToolTip"];
                return (obj == null) ? false : (bool)obj;
            }
            set
            {
                ViewState["ShowNvToolTip"] = value;
            }
        }

        /// <summary>
        /// 获取或设置导航按钮工具提示文本的格式。
        /// </summary>
        [Browsable(true), Themeable(true), ANPCategory("cat_Navigation"), ANPDefaultValue("def_NavigationToolTipTextFormatString"), ANPDescription("desc_NavigationToolTipTextFormatString")]
        public string NavigationToolTipTextFormatString
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.NavigationToolTipTextFormatString;
                object obj = ViewState["NvToolTipFormatString"];
                if (obj == null)
                {
                    if (ShowNavigationToolTip)
                        return SR.GetString("def_NavigationToolTipTextFormatString");
                    return null;
                }
                return (string)obj;
            }
            set
            {
                string tip = value;
                if (tip.Trim().Length < 1 && tip.IndexOf("{0}") < 0)
                    tip = "{0}";
                ViewState["NvToolTipFormatString"] = tip;
            }
        }

        /// <summary>
        /// 获取或设置页索引数值导航按钮上文本的显示格式。
        /// </summary>
        /// <value>
        /// 字符串，指定页索引数值按钮上文本的显示格式，默认值为<see cref="String.Empty" />，即未设置该属性。
        /// </value>
        /// <remarks>
        /// 使用NumericButtonTextFormatString属性指定页索引数值按钮的显示格式，如未设置该值时索引按钮文本将会是：1 2 3 ...，设置该值将改变索引按钮文本的显示格式，
        /// 如将该值设为“[{0}]”则索引文本会显示为：[1] [2] [3] ...，将该值设为“-{0}-”则会使索引文本变为：-1- -2- -3- ...。
        /// </remarks>
        [Browsable(true), Themeable(true), DefaultValue(""), ANPCategory("cat_Navigation"), ANPDescription("desc_NBTFormatString")]
        public string NumericButtonTextFormatString
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.NumericButtonTextFormatString;
                object obj = ViewState["NumericButtonTextFormatString"];
                return (obj == null) ? String.Empty : (string)obj;
            }
            set
            {
                ViewState["NumericButtonTextFormatString"] = value;
            }
        }

        /// <summary>
        /// 获取或设置当前页数值导航按钮上文本的显示格式。
        /// </summary>
        /// <value>
        /// 字符串，指定当前页索引数值按钮上文本的显示格式，默认值为<see cref="String.Empty" />，如果未设置该属性，则其值与NumericButtonTextFormatString属性值相同。
        /// </value>
        /// <remarks>
        /// 使用CurrentPageButtonTextFormatString属性指定当前页索引数值按钮文本的显示格式，如果希望当前页数值按钮的显示格式与其它数字页索引不同，则可设置该属性来自定义当前页索引文本的显示格式。
        /// </remarks>
        [Browsable(true), Themeable(true), DefaultValue(""), ANPCategory("cat_Navigation"), ANPDescription("desc_CPBTextFormatString")]
        public string CurrentPageButtonTextFormatString
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.CurrentPageButtonTextFormatString;
                object obj = ViewState["CurrentPageButtonTextFormatString"];
                return (obj == null) ? NumericButtonTextFormatString : (string)obj;
            }
            set
            {
                ViewState["CurrentPageButtonTextFormatString"] = value;
            }
        }


        /// <summary>
        /// 获取或设置分页导航按钮的类型，即使用文字还是图片。
        /// </summary>
        /// <remarks>
        /// 要使用图片按钮，您需要准备以下图片：从0到9的十个数值图片（当ShowPageIndex设为true时），第一页、上一页、下一页、最后一页及更多页（...）五个按钮图片（当ShowFirstLast及ShowPrevNext都设为true时），
        /// 若需要使当前页索引的数值按钮不同于别的页索引数值按钮，则还需准备当前页索引的按钮图片；
        /// 若需要使已禁用的第一页、上一页、下一页及最后一页按钮图片不同于正常的按钮图片，则还需准备这四个按钮在禁用状态下的图片；
        /// <p>
        ///   <b>图片文件的命名规则如下：</b>
        /// </p><p>
        ///   从0到9十张数值按钮图片必须命名为“数值+ButtonImageNameExtension+ButtonImageExtension”，其中的ButtonImageNameExtension可以不用设置，
        ///   ButtonImageExtension是图片文件的后缀名，如 .gif或 .jpg等可以在浏览器中显示的任何图片文件类型。如页索引“1”的图片文件可命名为“1.gif”或“1.jpg”，
        ///   当您有两套或更多套图片文件时，可以通过指定ButtonImageNameExtension属性值来区分不同套的图片，如第一套图片可以不用设ButtonImageNameExtension，则图片文件名类似于“1.gif”、“2.gif”等等，而第二套图片则设置ButtonImageNameExtension为“f”，图片文件名类似于“1f.gif”，“2f.gif”等等。
        /// </p><p>第一页按钮的图片文件名以“first”开头，上一页按钮图片名以“prev”开头，下一页按钮图片名以“next”开头，最后一页按钮图片名以“last”开头，更多页按钮图片名以“more”开头，是否使用ButtonImageNameExtension取决于数值按钮的设置及是否有更多套图片。</p>
        /// </remarks>
        /// <example>
        /// 以下代码片段示例如果使用图片按钮：
        ///      <p>
        ///        <code>
        ///          <![CDATA[
        /// <Webdiyer:AspNetPager runat="server" 
        ///        id="pager1" OnPageChanged="ChangePage"  
        ///        PagingButtonType="image" 	ImagePath="images" 
        ///        ButtonImageNameExtension="n" 
        ///        DisabledButtonImageNameExtension="g" 
        ///        ButtonImageExtension="gif" 
        ///        CpiButtonImageNameExtension="r" 
        ///        PagingButtonSpacing="10px"/>
        /// ]]>
        ///        </code>
        ///      </p>
        /// </example>
        [Browsable(true), Themeable(true), DefaultValue(PagingButtonType.Text), ANPCategory("cat_Navigation"), ANPDescription("desc_PagingButtonType")]
        public PagingButtonType PagingButtonType
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.PagingButtonType;
                object obj = ViewState["PagingButtonType"];
                return (obj == null) ? PagingButtonType.Text : (PagingButtonType)obj;
            }
            set
            {
                ViewState["PagingButtonType"] = value;
            }
        }

        /// <summary>
        /// 获取或设置页导航数值按钮的类型，该值仅当PagingButtonType设为Image时才有效。
        /// </summary>
        /// <remarks>
        /// 当您将PagingButtonType设为Image当又不想让页索引数值按钮使用图片时，可以将该值设为Text，这会使页索引数据按钮使用文本而不是图片按钮。
        /// </remarks>
        [Browsable(true), Themeable(true), DefaultValue(PagingButtonType.Text), ANPCategory("cat_Navigation"), ANPDescription("desc_NumericButtonType")]
        public PagingButtonType NumericButtonType
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.NumericButtonType;
                object obj = ViewState["NumericButtonType"];
                return (obj == null) ? PagingButtonType : (PagingButtonType)obj;
            }
            set
            {
                ViewState["NumericButtonType"] = value;
            }
        }

        /// <summary>
        /// 指定分页导航按钮（数字和上页、下页、首页、尾页）布局方式，可以将这些元素包含在&lt;li&gt;
        /// 或&lt;span&gt;标签中以方便应用CSS样式，默认不包含在任何标签中。
        /// </summary>
        /// <value>
        ///   一个<see cref="PagingButtonLayoutType"/>枚举。
        /// </value>
        [Browsable(true), Themeable(true), DefaultValue(PagingButtonLayoutType.None), ANPCategory("cat_Navigation"), ANPDescription("desc_PagingButtonLayoutType")]
        public PagingButtonLayoutType PagingButtonLayoutType
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.PagingButtonLayoutType;
                object obj = ViewState["PagingButtonLayoutType"];
                return (obj == null) ? PagingButtonLayoutType.None : (PagingButtonLayoutType)obj;
            }
            set
            {
                ViewState["PagingButtonLayoutType"] = value;
            }
        }

        /// <summary>
        /// 当前页数字按钮在所有数字分页按钮中的位置，可选值为：Beginning（最前）、End（最后）、Center（居中）和Fixed（默认固定）
        /// </summary>
        /// <value>
        ///   一个<see cref="PagingButtonPosition"/>枚举。
        /// </value>
        [Browsable(true), Themeable(true), DefaultValue(PagingButtonPosition.Fixed), ANPCategory("cat_Navigation"), ANPDescription("desc_CurrentPageButtonPosition")]
        public PagingButtonPosition CurrentPageButtonPosition
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.CurrentPageButtonPosition;
                object obj = ViewState["CurrentPageButtonPosition"];
                return (obj == null) ? PagingButtonPosition.Fixed : (PagingButtonPosition)obj;
            }
            set
            {
                ViewState["CurrentPageButtonPosition"] = value;
            }
        }

        /// <summary>
        /// 首页、上页、下页和尾页四个导航按钮在分页导航元素中的位置，可选值为：Left（全在左侧）、Right（全在右侧）、BothSides（默认值，分布于两侧）
        /// </summary>
        /// <value>
        ///   一个<see cref="NavigationButtonPosition"/>枚举。
        /// </value>
        [Browsable(true), Themeable(true), DefaultValue(NavigationButtonPosition.BothSides), ANPCategory("cat_Navigation"), ANPDescription("desc_NavigationButtonsPosition")]
        public NavigationButtonPosition NavigationButtonsPosition
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.NavigationButtonsPosition;
                object obj = ViewState["NavigationButtonsPosition"];
                return (obj == null) ? NavigationButtonPosition.BothSides : (NavigationButtonPosition)obj;
            }
            set
            {
                ViewState["NavigationButtonsPosition"] = value;
            }

        }

        /// <summary>
        /// 获取或设置第一页、上一页、下一页和最后一页按钮的类型，该值仅当PagingButtonType设为Image时才有效。
        /// </summary>
        /// <remarks>
        ///   当您将PagingButtonType设为Image但又不想让第一页、下一页、下一页和最后一页按钮使用图片，则可以将该值设为Text，这会使前面的四个按钮使用文本而不是图片按钮。
        /// </remarks>
        [Browsable(true), Themeable(true), ANPCategory("cat_Navigation"), DefaultValue(PagingButtonType.Text), ANPDescription("desc_NavigationButtonType")]
        public PagingButtonType NavigationButtonType
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.NavigationButtonType;
                object obj = ViewState["NavigationButtonType"];
                return (obj == null) ? PagingButtonType : (PagingButtonType)obj;
            }
            set
            {
                ViewState["NavigationButtonType"] = value;
            }
        }

        /// <summary>
        /// 获取或设置Url分页时分页按钮或超链接指向的目标窗口或框架的名称。
        /// </summary>
        /// <remark>
        ///   在Url分页时，如果您想在新的空白窗口或已知窗口或框架中打开分页后的页面，可以设置此属性值为目标窗口或框架的名称，如果未设置该属性，点击分页按钮后将在当前窗口或框架中打开新页面。
        /// </remark>
        [Browsable(true), Themeable(true), DefaultValue(""), TypeConverter(typeof(TargetConverter)), ANPCategory("cat_Navigation"), ANPDescription("desc_UrlPagingTarget")]
        public string UrlPagingTarget
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.UrlPagingTarget;
                return (string)ViewState["UrlPagingTarget"];
            }
            set
            {
                ViewState["UrlPagingTarget"] = value;
            }
        }

        /// <summary>
        /// 获取或设置“更多页”（...）按钮的类型，该值仅当PagingButtonType设为Image时才有效。
        /// </summary>
        /// <remarks>
        ///   当您将PagingButtonType设为Image但又不想让更多页（...）按钮使用图片时，可以将此值设为Text，这会使更多页按钮使用文本而不是图片按钮。
        /// </remarks>
        [Browsable(true), Themeable(true), ANPCategory("cat_Navigation"), DefaultValue(PagingButtonType.Text), ANPDescription("desc_MoreButtonType")]
        public PagingButtonType MoreButtonType
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.MoreButtonType;
                object obj = ViewState["MoreButtonType"];
                return (obj == null) ? PagingButtonType : (PagingButtonType)obj;
            }
            set
            {
                ViewState["MoreButtonType"] = value;
            }
        }

        /// <summary>
        /// 获取或设置分页导航按钮之间的间距。
        /// </summary>
        /// <value>
        ///   一个 Unit 值，默认值为5px。
        /// </value>
        [Browsable(true), Themeable(true), ANPCategory("cat_Navigation"), DefaultValue(typeof(Unit), "5px"), ANPDescription("desc_PagingButtonSpacing")]
        public Unit PagingButtonSpacing
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.PagingButtonSpacing;
                object obj = ViewState["PagingButtonSpacing"];
                return (obj == null) ? Unit.Pixel(5) : (Unit.Parse(obj.ToString()));
            }
            set
            {
                ViewState["PagingButtonSpacing"] = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值，该值指示是否在页导航元素中显示第一页和最后一页按钮。
        /// </summary>
        [Browsable(true), Themeable(true), ANPDescription("desc_ShowFirstLast"), ANPCategory("cat_Navigation"), DefaultValue(true)]
        public bool ShowFirstLast
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ShowFirstLast;
                object obj = ViewState["ShowFirstLast"];
                return (obj == null) ? true : (bool)obj;
            }
            set
            {
                ViewState["ShowFirstLast"] = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值，该值指示是否在页导航元素中显示上一页和下一页按钮。
        /// </summary>
        [Browsable(true), Themeable(true), ANPDescription("desc_ShowPrevNext"), ANPCategory("cat_Navigation"), DefaultValue(true)]
        public bool ShowPrevNext
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ShowPrevNext;
                object obj = ViewState["ShowPrevNext"];
                return (obj == null) ? true : (bool)obj;
            }
            set
            {
                ViewState["ShowPrevNext"] = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值，该值指示是否在页导航元素中显示页索引数值按钮。
        /// </summary>
        [Browsable(true), Themeable(true), ANPDescription("desc_ShowPageIndex"), ANPCategory("cat_Navigation"), DefaultValue(true)]
        public bool ShowPageIndex
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ShowPageIndex;
                object obj = ViewState["ShowPageIndex"];
                return (obj == null) ? true : (bool)obj;
            }
            set
            {
                ViewState["ShowPageIndex"] = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值，该值指示是否在页导航元素中显示更多页按钮。
        /// </summary>
        [Browsable(true), Themeable(true), ANPDescription("desc_ShowMoreButtons"), ANPCategory("cat_Navigation"), DefaultValue(true)]
        public bool ShowMoreButtons
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ShowMoreButtons;
                object obj = ViewState["ShowMoreButtons"];
                return (obj == null) ? true : (bool)obj;
            }
            set
            {
                ViewState["ShowMoreButtons"] = value;
            }
        }

        /// <summary>
        /// 获取或设置为第一页按钮显示的文本。
        /// </summary>
        [Browsable(true), Themeable(true), ANPDescription("desc_FirstPageText"), ANPCategory("cat_Navigation"), DefaultValue("&lt;&lt;")]
        public string FirstPageText
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.FirstPageText;
                object obj = ViewState["FirstPageText"];
                return (obj == null) ? "&lt;&lt;" : (string)obj;
            }
            set
            {
                ViewState["FirstPageText"] = value;
            }
        }

        /// <summary>
        /// 获取或设置为上一页按钮显示的文本。
        /// </summary>
        [Browsable(true), Themeable(true), ANPDescription("desc_PrevPageText"), ANPCategory("cat_Navigation"), DefaultValue("&lt;")]
        public string PrevPageText
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.PrevPageText;
                object obj = ViewState["PrevPageText"];
                return (obj == null) ? "&lt;" : (string)obj;
            }
            set
            {
                ViewState["PrevPageText"] = value;
            }
        }

        /// <summary>
        /// 获取或设置为下一页按钮显示的文本。
        /// </summary>
        [Browsable(true), Themeable(true), ANPDescription("desc_NextPageText"), ANPCategory("cat_Navigation"), DefaultValue("&gt;")]
        public string NextPageText
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.NextPageText;
                object obj = ViewState["NextPageText"];
                return (obj == null) ? "&gt;" : (string)obj;
            }
            set
            {
                ViewState["NextPageText"] = value;
            }
        }

        /// <summary>
        /// 获取或设置为最后一页按钮显示的文本。
        /// </summary>
        [Browsable(true), Themeable(true), ANPDescription("desc_LastPageText"), ANPCategory("cat_Navigation"), DefaultValue("&gt;&gt;")]
        public string LastPageText
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.LastPageText;
                object obj = ViewState["LastPageText"];
                return (obj == null) ? "&gt;&gt;" : (string)obj;
            }
            set
            {
                ViewState["LastPageText"] = value;
            }
        }

        /// <summary>
        /// 获取或设置在 <see cref="AspNetPager" /> 控件的页导航元素中同时显示的数值按钮的数目。
        /// </summary>
        [Browsable(true), Themeable(true), ANPDescription("desc_NumericButtonCount"), ANPCategory("cat_Navigation"), DefaultValue(10)]
        public int NumericButtonCount
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.NumericButtonCount;
                object obj = ViewState["NumericButtonCount"];
                return (obj == null) ? 10 : (int)obj;
            }
            set
            {
                ViewState["NumericButtonCount"] = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值，该值指定是否显示已禁用的按钮。
        /// </summary>
        /// <remarks>
        ///   该值用来指定是否显示已禁用的分页导航按钮，当当前页为第一页时，第一页和上一页按钮将被禁用，当当前页为最后一页时，下一页和最后一页按钮将被禁用，被禁用的按钮没有链接，在按钮上点击也不会有任何作用。
        /// </remarks>
        [Browsable(true), Themeable(true), ANPCategory("cat_Navigation"), ANPDescription("desc_ShowDisabledButtons"), DefaultValue(true)]
        public bool ShowDisabledButtons
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ShowDisabledButtons;
                object obj = ViewState["ShowDisabledButtons"];
                return (obj == null) ? true : (bool)obj;
            }
            set
            {
                ViewState["ShowDisabledButtons"] = value;
            }
        }

        #endregion

        #region Image Navigation Buttons

        /// <summary>
        /// 获取或设置当使用图片按钮时，图片文件的路径。
        /// </summary>
        [Browsable(true), Category("Appearance"), ANPDescription("desc_ImagePath"), DefaultValue(null)]
        public string ImagePath
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ImagePath;
                string imgPath = (string)ViewState["ImagePath"];
                if (imgPath != null)
                    imgPath = ResolveUrl(imgPath);
                return imgPath;
            }
            set
            {
                string imgPath = value.Trim().Replace("\\", "/");
                ViewState["ImagePath"] = (imgPath.EndsWith("/")) ? imgPath : imgPath + "/";
            }
        }

        /// <summary>
        /// 获取或设置当使用图片按钮时，图片的类型，如gif或jpg，该值即图片文件的后缀名。
        /// </summary>
        [Browsable(true), Themeable(true), Category("Appearance"), DefaultValue(".gif"), ANPDescription("desc_ButtonImageExtension")]
        public string ButtonImageExtension
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ButtonImageExtension;
                object obj = ViewState["ButtonImageExtension"];
                return (obj == null) ? ".gif" : (string)obj;
            }
            set
            {
                string ext = value.Trim();
                ViewState["ButtonImageExtension"] = (ext.StartsWith(".")) ? ext : ("." + ext);
            }
        }

        /// <summary>
        /// 获取或设置自定义图片文件名的后缀字符串，以区分不同类型的按钮图片。
        /// </summary>
        /// <remarks>
        ///   <note>
        ///     该值不是文件后缀名，而是为区分不同的图片文件而在图片名中加入的字符串，如：
        ///     当前有两套按钮图片，其中一套中的“1”的图片名可为“1f.gif”，另一套中的“1”的图片名可起为“1n.gif”，其中的f和n即为ButtonImageNameExtension。
        ///   </note>
        /// </remarks>
        [Browsable(true), Themeable(true), DefaultValue(null), Category("Appearance"), ANPDescription("desc_ButtonImageNameExtension")]
        public string ButtonImageNameExtension
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ButtonImageNameExtension;
                object obj = ViewState["ButtonImageNameExtension"];
                return (obj == null) ? null : (string)obj;
            }
            set
            {
                ViewState["ButtonImageNameExtension"] = value;
            }
        }

        /// <summary>
        /// 获取或设置当前页索引按钮的图片名后缀。
        /// </summary>
        /// <remarks>
        ///   当 <see cref="PagingButtonType" /> 设为 Image 时，该属性允许您设置当前页索引数值按钮使用的图片名后缀字符，因此可以使当前页索引按钮与其它页索引按钮使用不同的图片，若未设置该值，则默认值为<see cref="ButtonImageNameExtension" />，即当前页索引按钮与其它页索引按钮使用相同的图片。
        /// </remarks>
        [Browsable(true), Themeable(true), DefaultValue(null), Category("Appearance"), ANPDescription("desc_CpiButtonImageNameExtension")]
        public string CpiButtonImageNameExtension
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.CpiButtonImageNameExtension;
                object obj = ViewState["CpiButtonImageNameExtension"];
                return (obj == null) ? ButtonImageNameExtension : (string)obj;
            }
            set
            {
                ViewState["CpiButtonImageNameExtension"] = value;
            }
        }

        /// <summary>
        /// 获取或设置被禁用的分页元素使用的图片文件名后缀字符串，以便被禁用和未禁用的按钮可以使用不同的图片。
        /// </summary>
        [Browsable(true), Themeable(true), DefaultValue(null), Category("Appearance"), ANPDescription("desc_DisabledButtonImageNameExtension")]
        public string DisabledButtonImageNameExtension
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.DisabledButtonImageNameExtension;
                object obj = ViewState["DisabledButtonImageNameExtension"];
                return (obj == null) ? ButtonImageNameExtension : (string)obj;
            }
            set
            {
                ViewState["DisabledButtonImageNameExtension"] = value;
            }
        }

        /// <summary>
        /// 指定当使用图片按钮时，图片的对齐方式。
        /// </summary>
        [Browsable(true), ANPDescription("desc_ButtonImageAlign"), DefaultValue(ImageAlign.NotSet), Category("Appearance")]
        public ImageAlign ButtonImageAlign
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ButtonImageAlign;
                object obj = ViewState["ButtonImageAlign"];
                return (obj == null) ? ImageAlign.NotSet : (ImageAlign)obj;
            }
            set
            {
                if (value != ImageAlign.Right && value != ImageAlign.Left)
                    ViewState["ButtonImageAlign"] = value;
            }
        }


        #endregion

        #region Paging

        /// <summary>
        /// 获取或设置是否启用url来传递分页信息。
        /// </summary>
        /// <remarks>
        ///   启用Url分页方式是将用户欲访问的页索引通过Url来传递，由于该分页方式不使用页面向自身回发来传递数据，
        ///   所以每次分页时所有的数据都恢复为初始值或需要重新获取。使用Url分页方式不支持动态改变分页控件的属性值，因为无法将新的属性值通过Url来传递给下一页。
        /// </remarks>
        [Browsable(true), ANPCategory("cat_Paging"), DefaultValue(false), ANPDescription("desc_UrlPaging")]
        public bool UrlPaging
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.UrlPaging;
                object obj = ViewState["UrlPaging"];
                return (null == obj) ? false : (bool)obj;
            }
            set
            {
                ViewState["UrlPaging"] = value;
            }
        }

        /// <summary>
        /// 获取或设置当启用Url分页方式时，在url中表示要传递的页索引的参数的名称。
        /// </summary>
        /// <remarks>
        ///   该属性允许您自定义通过Url传递页索引时表示要传递的页索引的参数的名称，以避免与现有的参数名重复。
        ///   <p>该属性的默认值是“page”，即通过Url分页时，显示在浏览器地址栏中的Url类似于：</p>http://www.webdiyer.com/aspnetpager/samples/datagrid_url.aspx?page=2
        ///   <p>如将该值改为“pageindex”，则上面的Url将变为：</p><p>http://www.webdiyer.com/aspnetpager/samples/datagrid_url.aspx?pageindex=2 </p>
        ///   <note>当同一个页面上有两个分页控件为不同的数据实现分页时，必须为每个分页控件的UrlPageIndexName属性指定不同的值，否则一个分页控件分页将导致其它分页控件同时分页。</note>
        /// </remarks>
        [Browsable(true), DefaultValue("page"), ANPCategory("cat_Paging"), ANPDescription("desc_UrlPageIndexName")]
        public string UrlPageIndexName
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.UrlPageIndexName;
                object obj = ViewState["UrlPageIndexName"];
                return (null == obj) ? "page" : (string)obj;
            }
            set
            {
                ViewState["UrlPageIndexName"] = value;
            }
        }

        /// <summary>
        /// 获取或设置Url中指定每页显示记录数的参数的名称，或该值不为空或Url中该值对应的参数的值大于0，则PageSize属性将使用该参数的值做为每页显示的记录数。
        /// </summary>
        [Browsable(true), DefaultValue(""), ANPCategory("cat_Paging"), ANPDescription("desc_UrlPageSizeName")]
        public string UrlPageSizeName
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.UrlPageSizeName;
                return (string)ViewState["UrlPageSizeName"];
            }
            set
            {
                ViewState["UrlPageSizeName"] = value;
            }
        }

        /// <summary>
        /// 获取或设置当启用Url分页方式时，是否以反方向显示分页页索引参数，以利于优化搜索引擎搜索结果。
        /// </summary>
        /// <remarks>
        ///   该值设为true时，在Url分页时，Url中的当前页索引参数将与分页控件显示的当前页索引值反方向显示，如共有25页数据，分页控件的第1页将在Url显示为25页，分页控件的第25页将在Url中显示为第1页，分页控件中的第2页将在Url显示为24页，依次类推。
        /// </remarks>
        [Browsable(true), DefaultValue(false), ANPCategory("cat_Paging"), ANPDescription("desc_ReverseUrlPageIndex")]
        public bool ReverseUrlPageIndex
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ReverseUrlPageIndex;
                object obj = ViewState["ReverseUrlPageIndex"];
                return (null == obj) ? false : (bool)obj;
            }
            set
            {
                ViewState["ReverseUrlPageIndex"] = value;
            }
        }

        /// <summary>
        /// 获取或设置当前显示页的索引。
        /// </summary>
        /// <remarks>
        ///   使用此属性来确定在 AspNetPager 控件中当前显示的页，当前显示的页的数字索引将默认以红色字体加粗显示，用户可以通过<see cref="CurrentPageButtonClass"/>或<see cref="CurrentPageButtonStyle"/> 属性来自定义当前页数字索引的显示样式。此属性还用于以编程的方式控制分页控件当前显示的页。
        ///   <note>不同于起始值为0的DataGrid控件的CurrentPageIndex和GridView控件的PageIndex属性，AspNetPager的CurrentPageIndex值是从1开始的。</note>
        /// </remarks>
        [Browsable(true), ANPDescription("desc_CurrentPageIndex"), ANPCategory("cat_Paging"), DefaultValue(1)]
        public int CurrentPageIndex
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.CurrentPageIndex;
                object cpage = ViewState["CurrentPageIndex"];
                int pindex = (cpage == null) ? 1 : (int)cpage;
                if (pindex > PageCount && PageCount > 0)
                    return PageCount;
                if (pindex < 1)
                    return 1;
                return pindex;
            }
            set
            {
                int cpage = value;
                if (cpage < 1)
                    cpage = 1;
                else if (cpage > PageCount)
                    cpage = PageCount;
                ViewState["CurrentPageIndex"] = cpage;
                //if(!pageChangeEventHandled)
                //{
                //    OnPageChanging(new PageChangingEventArgs(cpage));
                //}
            }
        }

        /// <summary>
        /// 获取或设置需要分页的所有记录的总数。
        /// </summary>
        /// <remarks>
        ///   当页面第一次加载时，应以编程方式将有要分页的记录的总数赋予该属性，AspNetPager会将其保存的ViewState中并在页面回发时从ViewState中获取该值，因此避免了每次分页都要访问数据库而影响分页性能。AspNetPager根据要分页的所有数据的总项数和 <see cref="PageSize" /> 属性来计算显示所有数据需要的总页数，即 <see cref="PageCount" />的值。
        /// </remarks>
        [Browsable(false), ANPDescription("desc_RecordCount"), Category("Data"), DefaultValue(0)]
        public int RecordCount
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.RecordCount;
                object obj = ViewState["Recordcount"];
                return (obj == null) ? 0 : (int)obj;
            }
            set
            {
                ViewState["Recordcount"] = value;
            }
        }

        /// <summary>
        /// 获取当前页之后未显示的页的总数。
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int PagesRemain
        {
            get
            {
                return PageCount - CurrentPageIndex;
            }
        }

        /// <summary>
        /// 获取或设置每页显示的项数。
        /// </summary>
        /// <remarks>
        ///   该值获取或设置数据呈现控件每次要显示数据表中的的数据的项数，AspNetPager根据该值和 <see cref="RecordCount" /> 来计算显示所有数据需要的总页数，即 <see cref="PageCount" />的值。
        /// </remarks>
        /// <example>
        ///      以下示例将 <see cref="AspNetPager" /> 设置为允许每页显示8条数据：
        ///      <code>
        ///        <![CDATA[
        ///  ...
        ///  <Webdiyer:AspNetPager id="pager" runat="server" PageSize=8 OnPageChanged="ChangePage"/>
        ///  ...
        /// ]]>
        ///      </code>
        ///    </example>
        [Browsable(true), ANPDescription("desc_PageSize"), ANPCategory("cat_Paging"), DefaultValue(10)]
        public int PageSize
        {
            get
            {
                if (!string.IsNullOrEmpty(UrlPageSizeName) && !DesignMode)
                {
                    int pageSize;
                    if (int.TryParse(Page.Request.QueryString[UrlPageSizeName], out pageSize))
                    {
                        if (pageSize > 0)
                            return pageSize;
                    }
                }
                if (null != cloneFrom)
                    return cloneFrom.PageSize;
                object obj = ViewState["PageSize"];
                return (obj == null) ? 10 : (int)obj;
            }
            set
            {
                ViewState["PageSize"] = value;
            }
        }

        /// <summary>
        /// 获取在当前页之后还未显示的剩余记录的项数。
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int RecordsRemain
        {
            get
            {
                if (CurrentPageIndex < PageCount)
                    return RecordCount - (CurrentPageIndex * PageSize);
                return 0;
            }
        }

        /// <summary>
        /// 当前页数据记录的起始索引。
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int StartRecordIndex
        {
            get
            {
                //if (FillLastPage && RecordCount > PageSize && CurrentPageIndex == PageCount)
                //    return RecordCount - PageSize;
                return (CurrentPageIndex - 1) * PageSize + 1;
            }
        }


        /// <summary>
        /// 当前页最后一条记录的索引。
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int EndRecordIndex
        {
            get
            {
                return RecordCount - RecordsRemain;
            }
        }

        /// <summary>
        /// 获取所有要分页的记录需要的总页数。
        /// </summary>
        [Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public int PageCount
        {
            get
            {
                if (RecordCount == 0)
                    return 1;
                return (int)Math.Ceiling((double)RecordCount / (double)PageSize);
            }
        }


        #endregion

        #region Page index box


        /// <summary>
        /// 获取或设置页索引框的显示方式，以便用户输入或从下拉框中选择需要跳转到的页索引。
        /// </summary>
        /// <value>
        ///   一个<see cref="ShowPageIndexBox"/>枚举。
        /// </value>
        [Browsable(true), ANPCategory("cat_PageIndexBox"), DefaultValue(null), ANPDescription("desc_ShowPageIndexBox")]
        public ShowPageIndexBox ShowPageIndexBox
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ShowPageIndexBox;
                object obj = ViewState["ShowPageIndexBox"];
                return (obj == null) ? ShowPageIndexBox.Auto : (ShowPageIndexBox)obj;
            }
            set
            {
                ViewState["ShowPageIndexBox"] = value;
            }
        }

        /// <summary>
        /// 或者或设置页索引框的显示类型，可以是允许用户手工输入的文本框和只能选择的下拉框。
        /// </summary>
        /// <value>
        ///   一个<see cref="PageIndexBoxType"/>枚举。
        /// </value>
        [Browsable(true), ANPCategory("cat_PageIndexBox"), DefaultValue(null), ANPDescription("desc_PageIndexBoxType")]
        public PageIndexBoxType PageIndexBoxType
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.PageIndexBoxType;
                object obj = ViewState["PageIndexBoxType"];
                return (obj == null) ? PageIndexBoxType.TextBox : (PageIndexBoxType)obj;
            }
            set
            {
                ViewState["PageIndexBoxType"] = value;
            }
        }

        /// <summary>
        /// 获取或设置应用于页索引输入文本框或下拉框的CSS类名。
        /// </summary>
        [Browsable(true), ANPCategory("cat_PageIndexBox"), DefaultValue(null), ANPDescription("desc_PageIndexBoxClasss")]
        public string PageIndexBoxClass
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.PageIndexBoxClass;
                object obj = ViewState["PageIndexBoxClass"];
                return (obj == null) ? null : (string)obj;
            }
            set
            {
                if (value.Trim().Length > 0)
                    ViewState["PageIndexBoxClass"] = value;
            }
        }

        /// <summary>
        /// 获取或设置页索引输入文本框或下拉框的CSS样式文本。
        /// </summary>
        [Browsable(true), ANPCategory("cat_PageIndexBox"), DefaultValue(null), ANPDescription("desc_PageIndexBoxStyle")]
        public string PageIndexBoxStyle
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.PageIndexBoxStyle;
                object obj = ViewState["PageIndexBoxStyle"];
                return (obj == null) ? null : (string)obj;
            }
            set
            {
                if (value.Trim().Length > 0)
                    ViewState["PageIndexBoxStyle"] = value;
            }
        }


        /// <summary>
        /// 获取或设置页索引页索引输入文本框或下拉框前的文本字符串值。
        /// </summary>
        [Browsable(true), Themeable(true), ANPCategory("cat_PageIndexBox"), DefaultValue(null), ANPDescription("desc_TextBeforePageIndexBox")]
        public string TextBeforePageIndexBox
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.TextBeforePageIndexBox;
                object obj = ViewState["TextBeforePageIndexBox"];
                return (null == obj) ? null : (string)obj;
            }
            set
            {
                ViewState["TextBeforePageIndexBox"] = value;
            }
        }

        /// <summary>
        /// 获取或设置页索引页索引输入文本框或下拉框后的文本字符串值。
        /// </summary>
        [Browsable(true), Themeable(true), DefaultValue(null), ANPCategory("cat_PageIndexBox"), ANPDescription("desc_TextAfterPageIndexBox")]
        public string TextAfterPageIndexBox
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.TextAfterPageIndexBox;
                object obj = ViewState["TextAfterPageIndexBox"];
                return (null == obj) ? null : (string)obj;
            }
            set
            {
                ViewState["TextAfterPageIndexBox"] = value;
            }
        }

        /// <summary>
        /// 获取或设置提交按钮上的文本。
        /// </summary>
        [Browsable(true), Themeable(true), ANPCategory("cat_PageIndexBox"), DefaultValue("go"), ANPDescription("desc_SubmitButtonText")]
        public string SubmitButtonText
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.SubmitButtonText;
                object obj = ViewState["SubmitButtonText"];
                return (null == obj) ? "go" : (string)obj;
            }
            set
            {
                if (null == value)
                    value = "go";
                ViewState["SubmitButtonText"] = value;
            }
        }

        /// <summary>
        /// 获取或设置应用于提交按钮的CSS类名。
        /// </summary>
        [Browsable(true), ANPCategory("cat_PageIndexBox"), DefaultValue(null), ANPDescription("desc_SubmitButtonClass")]
        public string SubmitButtonClass
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.SubmitButtonClass;
                return (string)ViewState["SubmitButtonClass"];
            }
            set
            {
                ViewState["SubmitButtonClass"] = value;
            }
        }

        /// <summary>
        /// 获取或设置应用于提交按钮的CSS样式。
        /// </summary>
        [Browsable(true), ANPCategory("cat_PageIndexBox"), DefaultValue(null), ANPDescription("desc_SubmitButtonStyle")]
        public string SubmitButtonStyle
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.SubmitButtonStyle;
                return (string)ViewState["SubmitButtonStyle"];
            }
            set
            {
                ViewState["SubmitButtonStyle"] = value;
            }
        }

        /// <summary>
        /// 获取或设置提交按钮的图片路径，若该属性值为空，则提交按钮显示为普通按钮，否则显示为图片按钮并使用该属性的值做为图片路径。
        /// </summary>
        [Browsable(true), DefaultValue(""), Category("Appearance"), ANPDescription("desc_SubmitButtonImageUrl")]
        public string SubmitButtonImageUrl
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.SubmitButtonImageUrl;
                return (string)ViewState["SubmitButtonImageUrl"];
            }
            set
            {
                ViewState["SubmitButtonImageUrl"] = value;
            }
        }

        /// <summary>
        /// 获取或设置自动显示页索引输入文本框的最低起始页数。
        /// </summary>
        /// <remarks>
        ///   当 <see cref="ShowPageIndexBox" /> 设为Auto（默认）并且要分页的数据的总页数达到该值时会自动显示页索引输入文本框，默认值为30。该选项当 <see cref="ShowPageIndexBox" /> 设为Never或Always时没有任何作用。
        /// </remarks>
        [Browsable(true), Themeable(true), ANPDescription("desc_ShowBoxThreshold"), ANPCategory("cat_PageIndexBox"), DefaultValue(30)]
        public int ShowBoxThreshold
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ShowBoxThreshold;
                object obj = ViewState["ShowBoxThreshold"];
                return (null == obj) ? 30 : (int)obj;
            }
            set
            {
                ViewState["ShowBoxThreshold"] = value;
            }
        }


        #endregion

        #region CustomInfoSection

        /// <summary>
        /// 获取或设置显示用户自定义信息区的方式。
        /// </summary>
        /// <remarks>
        ///   该属性值设为Left或Right时会在分页导航元素左边或右边划出一个专门的区域来显示有关用户自定义信息，设为Never时不显示。
        /// </remarks>
        [Browsable(true), Themeable(true), ANPDescription("desc_ShowCustomInfoSection"), DefaultValue(ShowCustomInfoSection.Never), Category("Appearance")]
        public ShowCustomInfoSection ShowCustomInfoSection
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.ShowCustomInfoSection;
                object obj = ViewState["ShowCustomInfoSection"];
                return (null == obj) ? ShowCustomInfoSection.Never : (ShowCustomInfoSection)obj;
            }
            set
            {
                ViewState["ShowCustomInfoSection"] = value;
            }
        }

        /// <summary>
        /// 获取或设置用户自定义信息区文本的对齐方式。
        /// </summary>
        [Browsable(true), Category("Appearance"), DefaultValue(HorizontalAlign.NotSet), ANPDescription("desc_CustomInfoTextAlign")]
        public HorizontalAlign CustomInfoTextAlign
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.CustomInfoTextAlign;
                object obj = ViewState["CustomInfoTextAlign"];
                return (null == obj) ? HorizontalAlign.NotSet : (HorizontalAlign)obj;
            }
            set
            {
                ViewState["CustomInfoTextAlign"] = value;
            }
        }

        /// <summary>
        /// 获取或设置用户自定义信息区的宽度。
        /// </summary>
        [Browsable(true), Category("Appearance"), DefaultValue(typeof(Unit), "40%"), ANPDescription("desc_CustomInfoSectionWidth")]
        public Unit CustomInfoSectionWidth
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.CustomInfoSectionWidth;
                object obj = ViewState["CustomInfoSectionWidth"];
                return (null == obj) ? Unit.Percentage(40) : (Unit)obj;
            }
            set
            {
                ViewState["CustomInfoSectionWidth"] = value;
            }
        }

        /// <summary>
        /// 获取或设置应用于用户自定义信息区的级联样式表类名。
        /// </summary>
        [Browsable(true), Category("Appearance"), DefaultValue(null), ANPDescription("desc_CustomInfoClass")]
        public string CustomInfoClass
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.CustomInfoClass;
                object obj = ViewState["CustomInfoClass"];
                return (null == obj) ? CssClass : (string)obj;
            }
            set
            {
                ViewState["CustomInfoClass"] = value;
            }
        }

        /// <summary>
        /// 获取或设置应用于用户自定义信息区的CSS样式文本。
        /// </summary>
        /// <value>字符串值，要应用于用户自定义信息区的CSS样式文本。</value>
        [Browsable(true), Category("Appearance"), DefaultValue(null), ANPDescription("desc_CustomInfoStyle")]
        public string CustomInfoStyle
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.CustomInfoStyle;
                object obj = ViewState["CustomInfoStyle"];
                return (null == obj) ? Style.Value : (string)obj;
            }
            set
            {
                ViewState["CustomInfoStyle"] = value;
            }
        }

        /// <summary>
        /// 获取或设置在显示在用户自定义信息区的用户自定义HTML文本内容。
        /// </summary>
        /// <remarks>
        ///      可以用“%”+属性名+“%”来代替该属性的值，控件在运行时会将“%”+属性名+“%”替换为相应的属性的值，其中的“属性名”仅适用于下列属性：
        ///      <ul>
        ///        <li>RecordCount：记录总数</li>
        ///        <li>PageCount：总页数</li>
        ///        <li>CurrentPageIndex：当前页索引</li>
        ///        <li>StartRecordIndex：当前页起始记录的索引</li>
        ///        <li>EndRecordIndex：当前页最后一条记录的索引</li>
        ///        <li>PageSize：每页显示的记录项数</li>
        ///        <li>PagesRemain：当前页之后剩余的未显示的记录的页数</li>
        ///        <li>RecordsRemain：当前页之后剩余的未显示的记录总项数</li>
        ///      </ul>
        ///      属性名不区分大小写，所以“%RecordCount%”可以写为“%recordcount%”。
        ///    </remarks>
        ///    <example>
        ///      下面的代码片段显示如何设置AspNetPager的用户自定义信息：<br/>
        ///      <code>
        ///        <![CDATA[
        /// <webdiyer:aspnetpager id="AspNetPager1" runat="server" horizontalalign="Center" 
        /// onpagechanged="AspNetPager1_PageChanged" showcustominfosection="Left" width="100%" 
        /// CustomInfoHTML="当前页：%CurrentPageIndex%&nbsp;总页数：%PageCount%&nbsp;显示第%StartRecordIndex%条到%EndRecordIndex%条记录">
        /// </webdiyer:aspnetpager>
        /// ]]>
        ///      </code>
        ///    </example>
        [Browsable(true), Themeable(true), Category("Appearance"), DefaultValue("Page %CurrentPageIndex% of %PageCount%"), ANPDescription("desc_CustomInfoHTML")]
        public string CustomInfoHTML
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.CustomInfoHTML;
                object obj = ViewState["CustomInfoText"];
                return (null == obj) ? "Page %CurrentPageIndex% of %PageCount%" : (string)obj;
            }
            set
            {
                ViewState["CustomInfoText"] = value;
            }
        }

        #endregion

        #region Css class and styles

        /// <summary>
        /// 获取或设置AspNetPager分页控件当前页导航按钮的CSS样式文本。
        /// </summary>
        [Browsable(true), Category("Appearance"), ANPDescription("desc_CurrentPageButtonStyle"), DefaultValue(null)]
        public string CurrentPageButtonStyle
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.CurrentPageButtonStyle;
                object obj = ViewState["CPBStyle"];
                return (null == obj) ? null : (string)obj;
            }
            set
            {
                ViewState["CPBStyle"] = value;
            }
        }

        /// <summary>
        /// 获取或设置AspNetPager分页控件当前页导航按钮的级联样式表 (CSS) 类。
        /// </summary>
        [Browsable(true), Category("Appearance"), ANPDescription("desc_CurrentPageButtonClass"), DefaultValue(null)]
        public string CurrentPageButtonClass
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.CurrentPageButtonClass;
                object obj = ViewState["CPBClass"];
                return (null == obj) ? null : (string)obj;
            }
            set
            {
                ViewState["CPBClass"] = value;
            }
        }

        /// <summary>
        /// 获取或设置AspNetPager分页控件导航按钮（数字页索引、上页、下页、首页和尾页）的级联样式表 (CSS) 类。
        /// </summary>
        [Browsable(true), Category("Appearance"), Themeable(true), ANPDescription("desc_PagingButtonClass"), DefaultValue(null)]
        public string PagingButtonsClass
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.PagingButtonsClass;
                object obj = ViewState["PagingButtonsClass"];
                return (null == obj) ? null : (string)obj;
            }
            set
            {
                ViewState["PagingButtonsClass"] = value;
            }
        }

        /// <summary>
        /// 获取或设置AspNetPager分页控件导航按钮（数字页索引、上页、下页、首页和尾页）的CSS样式文本。
        /// </summary>
        [Browsable(true), Category("Appearance"), Themeable(true), ANPDescription("desc_PagingButtonStyle"), DefaultValue(null)]
        public string PagingButtonsStyle
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.PagingButtonsStyle;
                object obj = ViewState["PagingButtonsStyle"];
                return (null == obj) ? null : (string)obj;
            }
            set
            {
                ViewState["PagingButtonsStyle"] = value;
            }
        }

        /// <summary>
        /// 获取或设置AspNetPager分页控件首页和尾页导航按钮的级联样式表 (CSS) 类。
        /// </summary>
        /// <remarks>
        ///   若未设置该值，则使用 <see cref="PagingButtonsClass"/> 中设置的属性值。
        /// </remarks>
        [Browsable(true), Category("Appearance"), Themeable(true), ANPDescription("desc_FirstLastButtonsClass"), DefaultValue(null)]
        public string FirstLastButtonsClass
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.FirstLastButtonsClass;
                object obj = ViewState["FirstLastButtonsClass"];
                return (null == obj) ? PagingButtonsClass : (string)obj;
            }
            set
            {
                ViewState["FirstLastButtonsClass"] = value;
            }
        }

        /// <summary>
        /// 获取或设置AspNetPager分页控件首页和尾页导航按钮的CSS样式文本。
        /// </summary>
        /// <remarks>
        ///   若未设置该值，则使用 <see cref="PagingButtonsStyle"/> 中设置的属性值。
        /// </remarks>
        [Browsable(true), Category("Appearance"), Themeable(true), ANPDescription("desc_FirstLastButtonsStyle"), DefaultValue(null)]
        public string FirstLastButtonsStyle
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.FirstLastButtonsStyle;
                object obj = ViewState["FirstLastButtonsStyle"];
                return (null == obj) ? PagingButtonsStyle : (string)obj;
            }
            set
            {
                ViewState["FirstLastButtonsStyle"] = value;
            }
        }

        /// <summary>
        /// 获取或设置AspNetPager分页控件上页和下页导航按钮的级联样式表 (CSS) 类。
        /// </summary>
        /// <remarks>
        ///   若未设置该值，则使用 <see cref="PagingButtonsClass"/> 中设置的属性值。
        /// </remarks>
        [Browsable(true), Category("Appearance"), Themeable(true), ANPDescription("desc_PrevNextButtonsClass"), DefaultValue(null)]
        public string PrevNextButtonsClass
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.PrevNextButtonsClass;
                object obj = ViewState["PrevNextButtonsClass"];
                return (null == obj) ? PagingButtonsClass : (string)obj;
            }
            set
            {
                ViewState["PrevNextButtonsClass"] = value;
            }
        }

        /// <summary>
        /// 获取或设置AspNetPager分页控件上页和下页导航按钮的CSS样式文本。
        /// </summary>
        /// <remarks>
        ///   若未设置该值，则使用 <see cref="PagingButtonsStyle"/> 中设置的属性值。
        /// </remarks>
        [Browsable(true), Category("Appearance"), Themeable(true), ANPDescription("desc_PrevNextButtonsStyle"), DefaultValue(null)]
        public string PrevNextButtonsStyle
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.PrevNextButtonsStyle;
                object obj = ViewState["PrevNextButtonsStyle"];
                return (null == obj) ? PagingButtonsStyle : (string)obj;
            }
            set
            {
                ViewState["PrevNextButtonsStyle"] = value;
            }
        }

        /// <summary>
        /// 获取或设置AspNetPager分页控件更多页（...）导航按钮的级联样式表 (CSS) 类。
        /// </summary>
        /// <remarks>
        ///   若未设置该值，则使用 <see cref="PagingButtonsClass"/> 中设置的属性值。
        /// </remarks>
        [Browsable(true), Category("Appearance"), Themeable(true), ANPDescription("desc_MoreButtonsClass"), DefaultValue(null)]
        public string MoreButtonsClass
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.MoreButtonsClass;
                object obj = ViewState["MoreButtonsClass"];
                return (null == obj) ? PagingButtonsClass : (string)obj;
            }
            set
            {
                ViewState["MoreButtonsClass"] = value;
            }
        }

        /// <summary>
        /// 获取或设置AspNetPager分页控件更多页（...）导航按钮的CSS样式文本。
        /// </summary>
        /// <remarks>
        ///   若未设置该值，则使用 <see cref="PagingButtonsStyle"/> 中设置的属性值。
        /// </remarks>
        [Browsable(true), Category("Appearance"), Themeable(true), ANPDescription("desc_MoreButtonsStyle"), DefaultValue(null)]
        public string MoreButtonsStyle
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.MoreButtonsStyle;
                object obj = ViewState["MoreButtonsStyle"];
                return (null == obj) ? PagingButtonsStyle : (string)obj;
            }
            set
            {
                ViewState["MoreButtonsStyle"] = value;
            }
        }

        #endregion

        #region Others

        /// <summary>
        /// 获取或设置要克隆属性值及事件处理程序的另一个 AspNetPager 的ID。
        /// </summary>
        /// <remarks>
        ///       当一个页面上同时有两个或更多 AspNetPager 分页控件为相同的数据控件实现分页时，可以只设置一个 AspNetPager 的相关属性及事件处理程序，其它 AspNetPager 控件可以将 CloneFrom 属性指向该控件，自动克隆该控件的属性及事件处理程序而无需重复设置属性及编写事件处理程序，
        ///       在Url分页模式下，如果有两个或更多 AspNetPager 同时处理相同的数据或为相同的数据控件实现分页，则应该只设置一个 AspNetPager 的相关属性及编写事件处理程序，其它 AspNetPager 控件通过指定 CloseFrom 属性从该控件自动复制相关属性及事件处理程序，否则因为Url分页模式是在页面第一次加载时引发分页事件，所以如果有多个分页控件为相同的数据分页，每个 AspNetPager 的分页事件都被引发，从而导致数据被多次获取及绑定。
        ///     </remarks>
        ///     <example>
        ///       下面的示例使用两个AspNetPager为同一个Repeater进行分页，只需要设置第一个 AspNetPager 的相关属性及编写事件处理程序，第二个 AspNetPager 分页控件将 CloseFrom 属性设置为第一个 AspNetPager 的ID，从而实现自动复制第一个 AspNetPager 的相关属性及事件处理程序的目的：
        ///       <code>
        ///         <![CDATA[
        /// <%@ Register Assembly="AspNetPager" Namespace="Wuqi.Webdiyer" TagPrefix="webdiyer" %>
        /// <%@Import NameSpace="System.Data"%>
        /// <%@Import NameSpace="System.Data.SqlClient"%>
        /// <script runat="server" Language="C#">
        /// void Page_Load(object sender, EventArgs e)
        ///     {
        ///         if (!IsPostBack)
        ///         {
        ///             int totalOrders = (int)SqlHelper.ExecuteScalar(CommandType.StoredProcedure, "P_GetOrderNumber");
        ///             AspNetPager1.RecordCount = totalOrders;
        ///             bindData();
        ///         }
        ///     }
        /// 
        ///  void bindData()
        ///     {
        ///         Repeater1.DataSource = SqlHelper.ExecuteReader(CommandType.StoredProcedure,"P_GetPagedOrders2005",
        ///             new SqlParameter("@startIndex", AspNetPager1.StartRecordIndex),
        ///             new SqlParameter("@pageSize", AspNetPager1.PageSize));
        ///         Repeater1.DataBind();
        ///     }
        /// 
        ///  void AspNetPager1_PageChanged(object src, EventArgs e)
        ///     {
        ///         bindData();
        ///     }
        /// </script>
        /// <HTML><HEAD>
        /// <TITLE> AspNetPager Samples </TITLE>
        /// <META NAME="Author" CONTENT="Webdiyer (www.webdiyer.com)">
        /// </HEAD>
        /// 
        /// <BODY>
        /// <form runat="server">
        ///   <webdiyer:AspNetPager ID="AspNetPager1" runat="server" Width="100%" HorizontalAlign="right" PageSize="8" OnPageChanged="AspNetPager1_PageChanged">
        ///         </webdiyer:AspNetPager>
        ///         <asp:Repeater ID="Repeater1" runat="server">
        ///         <HeaderTemplate>
        ///         <table width="100%" border="1" cellspacing="0" cellpadding="4" style="border-collapse:collapse">
        ///         <tr style="backGround-color:#CCCCFF"><th style="width:15%"><asp:Literal ID="Literal1" runat="server" Text="<%$Resources:LocalizedText,orderid%>" /></th><th style="width:15%"><asp:Literal ID="Literal3" runat="server" Text="<%$Resources:LocalizedText,orderdate%>" /></th><th style="width:30%"><asp:Literal ID="Literal5" runat="server" Text="<%$Resources:LocalizedText,companyname%>" /></th><th style="width:20%"><asp:Literal ID="Literal2" runat="server" Text="<%$Resources:LocalizedText,customerid%>" /></th><th style="width:20%"><asp:Literal ID="Literal4" runat="server" Text="<%$Resources:LocalizedText,employeename%>" /></th></tr>
        ///         </HeaderTemplate>
        ///         <ItemTemplate>
        ///         <tr style="background-color:#FAF3DC">
        ///         <td><%#DataBinder.Eval(Container.DataItem,"orderid")%></td>
        ///         <td><%#DataBinder.Eval(Container.DataItem,"orderdate","{0:d}")%></td>
        ///         <td><%#DataBinder.Eval(Container.DataItem, "companyname")%></td>
        ///         <td><%#DataBinder.Eval(Container.DataItem,"customerid")%></td>
        ///         <td><%#DataBinder.Eval(Container.DataItem,"employeename")%></td>
        ///         </tr>
        ///         </ItemTemplate>
        ///         <FooterTemplate>
        ///         </table>
        ///         </FooterTemplate>
        ///         </asp:Repeater>
        ///         <webdiyer:AspNetPager ID="AspNetPager2" runat="server" CloneFrom="AspNetPager1">
        ///         </webdiyer:AspNetPager>
        ///         </form>
        /// </BODY>
        /// </HTML>
        ///         ]]>
        ///       </code>
        ///     </example>
        [Browsable(true), Themeable(false), TypeConverter(typeof(AspNetPagerIDConverter)), Category("Behavior"), DefaultValue(false), ANPDescription("desc_CloneFrom")]
        public string CloneFrom
        {
            get
            {
                return (string)ViewState["CloneFrom"];
            }
            set
            {
                if (null != value && String.Empty == value.Trim())
                    throw new ArgumentNullException("CloneFrom", "The Value of property CloneFrom can not be empty string!");
                if (ID.Equals(value, StringComparison.OrdinalIgnoreCase))
                    throw new ArgumentException("The property value of CloneFrom can not be set to control itself!", "CloneFrom");
                ViewState["CloneFrom"] = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值，该值指定是否为控件应用主题。
        /// </summary>
        public override bool EnableTheming
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.EnableTheming;
                return base.EnableTheming;
            }
            set
            {
                base.EnableTheming = value;
            }
        }

        /// <summary>
        /// 获取或设置要应用于控件的皮肤的ID。
        /// </summary>
        public override string SkinID
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.SkinID;
                return base.SkinID;
            }
            set
            {
                base.SkinID = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值，该值指定是否启用URL重写。
        /// </summary>
        /// <remarks>
        ///   设置该属性值为true时，UrlPaging属性值将自动变为true，即自动启用Url分页。
        /// </remarks>
        [Browsable(true), Themeable(true), Category("Behavior"), DefaultValue(false), ANPDescription("desc_EnableUrlWriting")]
        public bool EnableUrlRewriting
        {
            get
            {
                object obj = ViewState["UrlRewriting"];
                if (null == obj)
                {
                    if (null != cloneFrom)
                        return cloneFrom.EnableUrlRewriting;
                    return false;
                }
                return (bool)obj;
            }
            set
            {
                ViewState["UrlRewriting"] = value;
                if (value)
                    UrlPaging = true;
            }
        }

        /// <summary>
        /// 获取或设置要URL的重写格式。
        /// </summary>
        /// <remarks>
        ///       该属性仅当 UrlPaging 的值为true时才有效。要重写的Url路径可以是相对于当前的Url路径，如：../pagelist_{0}.aspx ，也可以是绝对路径，如：http://www.webdiyer.com/articles/{0}.aspx ，用“{0}”占位符来表示AspNetPager分页控件的当页页索引值，用“%参数名%”表示Url中相应的参数的值。如果不设置该值，默认值为当前页面路径加下划线后跟页索引，
        ///       如当前Url是 http://www.webdiyer.com/articlelist.aspx ，不设置 UrlRewritePattern 时，第一页的默认路径就是 http://www.webdiyer.com/articlelist_1.aspx ，第二页就是 http://www.webdiyer.com/articlelist_2.asp ，依次类推。以下举例说明如何设置重写格式：
        ///       <p>
        ///         <![CDATA[1、原始Url：http://www.webdiyer.com/articlelist.aspx?type=aspnet&page=2]]>（其中参数page=2为AspNetPager传递的页索引参数，这个参数名可以通过<see cref="UrlPageIndexName"/>属性设置，默认值为“page”）<br/>
        ///         重写为：http://www.webdiyer.com/articlelist/aspnet/2.aspx ，则应设置：UrlRewritePattern="./articlelist/%type%/{0}.aspx";
        ///       </p>
        ///       <p>
        ///         <![CDATA[2、原始Url：http://www.webdiyer.com/articlelist.aspx?type=dotnet&subtype=aspnet&page=3]]> （其中参数page=3为AspNetPager传递的页索引参数，这个参数名可以通过<see cref="UrlPageIndexName"/>属性设置，默认值为“page”）<br/>
        ///         重写为：http://www.webdiyer.com/articlelist/dotnet/aspnet/page_3.aspx ，则应设置：UrlRewritePattern="./articlelist/%type%/%subtype%/page_{0}.aspx";
        ///       </p>
        ///     </remarks>
        ///     <example>
        ///       下面的示例中演示如何设置 UrlRewritePattern 属性：
        ///       <code>
        ///         <![CDATA[
        /// <webdiyer:aspnetpager id="AspNetPager1" runat="server" horizontalalign="Center" width="100%"
        /// UrlPaging="true" EnableUrlRewriting="true" UrlRewritePattern="./listpage_{0}.aspx" 
        /// OnPageChanged="AspNetPager1_PageChanged"></webdiyer:aspnetpager>
        ///       ]]>
        ///       </code>
        ///     </example>
        [Browsable(true), Themeable(true), Category("Behavior"), DefaultValue(null), ANPDescription("desc_UrlRewritePattern")]
        public string UrlRewritePattern
        {
            get
            {
                object obj = ViewState["URPattern"];
                if (null == obj)
                {
                    if (null != cloneFrom)
                        return cloneFrom.UrlRewritePattern;
                    if (EnableUrlRewriting)
                    {
                        if (!DesignMode)
                        {
                            string filePath = Page.Request.FilePath;
                            return Path.GetFileNameWithoutExtension(filePath) + "_{0}" + Path.GetExtension(filePath);
                        }
                    }
                    return null;
                }
                return (string)obj;
            }
            set
            {
                ViewState["URPattern"] = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值，该值指定是否总是显示AspNetPager分页按件，即使要分页的数据只有一页。
        /// </summary>
        /// <remarks>
        ///   默认情况下，当要分页的数据只有一页时，AspNetPager默认会自动危险期而不在页面上显示任何可见内容，将此属性值设为true时，即使总页数只有一页，AspNetPager也将显示分页导航元素。
        /// </remarks>
        [Browsable(true), Themeable(true), Category("Behavior"), DefaultValue(false), ANPDescription("desc_AlwaysShow")]
        public bool AlwaysShow
        {
            get
            {
                object obj = ViewState["AlwaysShow"];
                if (null == obj)
                {
                    if (null != cloneFrom)
                        return cloneFrom.AlwaysShow;
                    return false;
                }
                return (bool)obj;
            }
            set
            {
                ViewState["AlwaysShow"] = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值，该值指定是否总是显示第一页和最后一页数字页索引按钮。
        /// </summary>
        [Browsable(true), Themeable(true), Category("Behavior"), DefaultValue(false), ANPDescription("desc_AlwaysShowFirstLastPageNumber")]
        public bool AlwaysShowFirstLastPageNumber
        {
            get
            {
                object obj = ViewState["AlwaysShowFirstLastPageNumber"];
                if (null == obj)
                {
                    if (null != cloneFrom)
                        return cloneFrom.AlwaysShowFirstLastPageNumber;
                    return false;
                }
                return (bool)obj;
            }
            set
            {
                ViewState["AlwaysShowFirstLastPageNumber"] = value;
            }
        }

        /// <summary>
        /// 获取或设置一个值，该值批示是否允许控件中的内容换行。
        /// </summary>
        /// <remarks>
        ///   <note>
        ///     AspNetPager 控件重写该属性，不允许内容换行。
        ///   </note>
        /// </remarks>
        public override bool Wrap
        {
            get
            {
                return base.Wrap;
            }
            set
            {
                base.Wrap = false;
            }
        }

        /// <summary>
        /// 获取或设置当用户输入的页索引超出范围（大于最大页索引或小于最小页索引）时在客户端显示的错误信息。
        /// </summary>
        [Browsable(true), Themeable(true), ANPDescription("desc_PIOutOfRangeMsg"), ANPDefaultValue("def_PIOutOfRangerMsg"), Category("Data")]
        public string PageIndexOutOfRangeErrorMessage
        {
            get
            {
                object obj = ViewState["PIOutOfRangeErrorMsg"];
                if (null == obj)
                {
                    if (null != cloneFrom)
                        return cloneFrom.PageIndexOutOfRangeErrorMessage;
                    return SR.GetString("def_PIOutOfRangerMsg");
                }
                return (string)obj;
            }
            set
            {
                ViewState["PIOutOfRangeErrorMsg"] = value;
            }
        }

        /// <summary>
        /// 获取或设置当用户输入无效的页索引（负值或非数字）时在客户端显示的错误信息。
        /// </summary>
        [Browsable(true), Themeable(true), ANPDescription("desc_InvalidPIErrorMsg"), ANPDefaultValue("def_InvalidPIErrorMsg"), Category("Data")]
        public string InvalidPageIndexErrorMessage
        {
            get
            {
                object obj = ViewState["InvalidPIErrorMsg"];
                if (null == obj)
                {
                    if (null != cloneFrom)
                        return cloneFrom.InvalidPageIndexErrorMessage;
                    return SR.GetString("def_InvalidPIErrorMsg");
                }
                return (string)obj;
            }
            set
            {
                ViewState["InvalidPIErrorMsg"] = value;
            }
        }

        /// <summary>
        /// 分页控件自定义信息区和分页导航区使用的布局方式。
        /// </summary>
        /// <value>
        ///   一个<see cref="LayoutType"/>枚举。
        /// </value>
        [Browsable(true), Themeable(true), ANPDescription("desc_LayoutType"), ANPDefaultValue("Div"), Category("Appearance")]
        public LayoutType LayoutType
        {
            get
            {
                if (null != cloneFrom)
                    return cloneFrom.LayoutType;
                object obj = ViewState["LayoutType"];
                return (null == obj) ? LayoutType.Div : (LayoutType)obj;
            }
            set
            {
                ViewState["LayoutType"] = value;
            }
        }

        #endregion

    }

}
